package com.jimbo.buildRunBat;

import lombok.Data;

import java.io.*;

/**
 * 保存类 PACKAGE_NAME Save
 *
 * @author LiuJingPing
 * @date 2019/11/13 15:25
 */
@Data
public class Save {

    public static final String START_MODE_AUTOMATIC = "Automatic";
    public static final String START_MODE_MANUAL = "Manual";

    /**
     * jar 包
     */
    private File jarFile;
    /**
     * 配置文件
     */
    private File configFile;
    /**
     * 保存地址
     */
    private String savePath;
    /**
     * 保存文件名称
     */
    private String saveFolderName;

    /**
     * 服务启动模式
     */
    private String startMode;

    /**
     * 服务描述
     */
    private String serviceDesc;

    private Integer debugPort;

    private Integer moitorPort;

    private String saveAbsolutePath;

    public Save(File jarFile,
            File configFile,
            String savePath,
            String saveFolderName,
            String startMode,
            String serviceDesc,
            Integer debugPort,
            Integer moitorPort) {
        this.jarFile = jarFile;
        this.configFile = configFile;
        this.savePath = savePath;
        this.saveFolderName = saveFolderName;
        this.startMode = startMode;
        this.serviceDesc = serviceDesc;
        this.saveAbsolutePath = savePath + "/" + saveFolderName;
        this.debugPort = debugPort;
        this.moitorPort = moitorPort;
    }

    boolean build() throws IOException {
        generateFileDirectories();
        saveJar();
        saveConfigFile();
        generateExe();
        generateRunXml();
        generateServerInstallBat();
        generateServerUnInstallBat();
        generateServerStartBat();
        generateServerStopBat();
        generateStartBat();
        return true;
    }

    private void generateFileDirectories() {
        File file = new File(saveAbsolutePath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    private void saveJar() throws IOException {
        FileInputStream inputStream = new FileInputStream(jarFile);
        writerStream(inputStream, saveAbsolutePath + "/" + saveFolderName + ".jar");
    }

    private void saveConfigFile() throws IOException {
        if (configFile != null) {
            File configFileDirectories = new File(saveAbsolutePath + "/config");
            if (!configFileDirectories.exists()) {
                configFileDirectories.mkdirs();
            }
            FileInputStream inputStream = new FileInputStream(configFile);
            writerStream(inputStream, saveAbsolutePath + "/config/" + configFile.getName());
        }
    }

    private void generateExe() throws IOException {
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("source.exe");
        writerStream(inputStream, saveAbsolutePath + "/" + saveFolderName + ".exe");
    }

    private void generateRunXml() throws IOException {
        String jmxStr = "-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=" + this.moitorPort + " -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false ";
        String debugStr = " -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + debugPort;
        String str = "<configuration>\n"
                + "  <id>" + saveFolderName + "-Server</id>\n"
                + "  <name>" + saveFolderName + "-Server</name>\n"
                + "  <description>" + this.serviceDesc + "</description>\n"
                + "  <executable>java</executable>\n"
                + "  <arguments>" + (moitorPort == null ? "" : jmxStr) + (debugPort == null ? "" : debugStr) + " -jar " + saveFolderName + ".jar " + (configFile == null ? "" : "-Dspring.config.location=config/" + configFile.getName()) + "</arguments>" + "\n"
                + "  <startmode>" + this.startMode + "</startmode>\n"
                + "  <logpath>logs/service</logpath>\n"
                + "  <logmode>rotate</logmode>\n"
                + "</configuration>";
        File file = new File(saveAbsolutePath + "/" + saveFolderName + ".xml");
        if (!file.exists()) {
            file.createNewFile();
        }
        saveStrToFile(str, file.getAbsolutePath());
    }

    private void generateServerInstallBat() throws IOException {
        String str = "@echo off\n"
                + "fltmc>nul||cd/d %~dp0&&mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"%~nx0\",\"%1\",\"\",\"runas\",1)(window.close)&&exit\n"
                + "if not \"%OS%\"==\"Windows_NT\" exit\n"
                + "title " + saveFolderName + "Server-install\n"
                + "cd /D %~dp0\n"
                + "cd %cd%\n"
                + ".\\" + saveFolderName + ".exe install\n"
                + "pause";
        File file = new File(saveAbsolutePath + "/" + saveFolderName + "Server-install.bat");
        if (!file.exists()) {
            file.createNewFile();
        }
        saveStrToFile(str, file.getAbsolutePath());
    }

    private void generateServerUnInstallBat() throws IOException {
        String str = "@echo off\n"
                + "fltmc>nul||cd/d %~dp0&&mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"%~nx0\",\"%1\",\"\",\"runas\",1)(window.close)&&exit\n"
                + "if not \"%OS%\"==\"Windows_NT\" exit\n"
                + "title " + saveFolderName + "Server-uninstall\n"
                + "cd /D %~dp0\n"
                + "cd %cd%\n"
                + ".\\" + saveFolderName + ".exe uninstall\n"
                + "pause";
        File file = new File(saveAbsolutePath + "/" + saveFolderName + "Server-uninstall.bat");
        if (!file.exists()) {
            file.createNewFile();
        }
        saveStrToFile(str, file.getAbsolutePath());
    }

    private void generateServerStartBat() throws IOException {
        String str = "@echo off\n"
                + "fltmc>nul||cd/d %~dp0&&mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"%~nx0\",\"%1\",\"\",\"runas\",1)(window.close)&&exit\n"
                + "if not \"%OS%\"==\"Windows_NT\" exit\n"
                + "title " + saveFolderName + "Server-start\n"
                + "set srvname=\"" + saveFolderName + "-Server\"\n"
                + "if %srvname%. == . goto end\n"
                + ":chkit\n"
                + "set svrst=0\n"
                + "for /F \"tokens=1* delims= \" %%a in ('net start') do if /I \"%%a %%b\" == %srvname% set svrst=1\n"
                + "if %svrst% == 0 net start %srvname%\n"
                + ":end\n"
                + "pause";
        File file = new File(saveAbsolutePath + "/" + saveFolderName + "Server-start.bat");
        if (!file.exists()) {
            file.createNewFile();
        }
        saveStrToFile(str, file.getAbsolutePath());
    }

    private void generateServerStopBat() throws IOException {
        String str = "@echo off\n"
                + "fltmc>nul||cd/d %~dp0&&mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"%~nx0\",\"%1\",\"\",\"runas\",1)(window.close)&&exit\n"
                + "if not \"%OS%\"==\"Windows_NT\" exit\n"
                + "title " + saveFolderName + "Server-stop\n"
                + "set srvname=\"" + saveFolderName + "-Server\"\n"
                + "if %srvname%. == . goto end\n"
                + "net Stop %srvname%\n"
                + "pause";
        File file = new File(saveAbsolutePath + "/" + saveFolderName + "Server-stop.bat");
        if (!file.exists()) {
            file.createNewFile();
        }
        saveStrToFile(str, file.getAbsolutePath());
    }

    private void generateStartBat() throws IOException {
        String str = "@echo off\n"
                + "title " + saveFolderName + "Server-start\n"
                + "if \"%1\" == \"max\" goto top\n"
                + "start \"\" /max \"%~nx0\" max\n"
                + "exit\n"
                + ":top\n"
                + "cd %cd%\n"
                + "java " + (debugPort == null ? "" : "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=" + debugPort) + " -jar " + saveFolderName + ".jar" + (configFile == null ? "" : " -Dspring.config.location=%cd%\\config\\" + configFile.getName());
        File file = new File(saveAbsolutePath + "/" + saveFolderName + "start.bat");
        if (!file.exists()) {
            file.createNewFile();
        }
        saveStrToFile(str, file.getAbsolutePath());
    }

    private void writerStream(InputStream inputStream, String writePath) throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream out = new FileOutputStream(new File(writePath));
        while ((index = inputStream.read(bytes)) != -1) {
            out.write(bytes, 0, index);
            out.flush();
        }
        out.close();
        inputStream.close();
    }

    private void saveStrToFile(String str, String filePath) {
        try (BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(filePath)), "utf-8"));) {
            bufferedWriter.write(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
